package cn.stylefeng.roses.kernel.ca.server.core.sso;

import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.stylefeng.roses.kernel.ca.api.RedirectUrlCreatorApi;
import cn.stylefeng.roses.kernel.ca.api.constants.CaServerConstants;
import cn.stylefeng.roses.kernel.ca.api.enums.SsoLoginPageType;
import cn.stylefeng.roses.kernel.ca.api.exception.CaServerException;
import cn.stylefeng.roses.kernel.ca.api.exception.enums.CaServerExceptionEnum;
import cn.stylefeng.roses.kernel.ca.api.expander.CaServerConfigExpander;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import cn.stylefeng.roses.kernel.rule.util.RedirectUrlBuildUtil;
import org.springframework.stereotype.Service;

import java.util.HashMap;

/**
 * 默认的url创建工厂
 *
 * @author fengshuonan
 * @date 2021/1/22 10:02
 */
@Service
public class DefaultRedirectUrlCreator implements RedirectUrlCreatorApi {

    @Override
    public String createClientSsoCallbackUrl(Long clientId, String secretUserInfo, String originRedirectUrl,
                                             String clientConfigCallbackUrl) {

        // 1. 判断两个回调url是否同时为空，为空则会异常
        if (StrUtil.isAllBlank(originRedirectUrl, clientConfigCallbackUrl)) {
            throw new CaServerException(CaServerExceptionEnum.CALLBACK_URL_NULL);
        }

        // 2. 组装token参数和callback参数，准备拼接
        HashMap<String, Object> params = new HashMap<>();
        params.put(CaServerConfigExpander.getCallbackUrlTokenFieldName(), secretUserInfo);
        if (StrUtil.isNotBlank(originRedirectUrl)) {
            params.put(CaServerConstants.CA_CALLBACK_FIELD_NAME, originRedirectUrl);
        }

        return RedirectUrlBuildUtil.createRedirectUrl(clientConfigCallbackUrl, params);
    }

    @Override
    public String createClientSsoCallbackErrorUrl(String ssoCallback, String errorCode) {
        HashMap<String, Object> params = new HashMap<>();
        params.put(CaServerConfigExpander.getCallbackUrlErrorCodeFieldName(), errorCode);
        return RedirectUrlBuildUtil.createRedirectUrl(ssoCallback, params);
    }

    @Override
    public String createLoginPageUrl(Integer ssoLoginUrlType, String customLoginUrl, String errorCode) {

        String redirectLoginUrl = null;

        // 如果是应用自定义的登录界面
        if (SsoLoginPageType.CUSTOM.getCode().equals(ssoLoginUrlType)) {
            redirectLoginUrl = customLoginUrl;
        }

        // 如果是统一的登录界面
        if (SsoLoginPageType.UNIFY.getCode().equals(ssoLoginUrlType)) {
            redirectLoginUrl = CaServerConfigExpander.getUnifyLoginUrl();
        }

        // 拼接errorCode参数
        HashMap<String, Object> redirectParams = new HashMap<>();
        redirectParams.put(CaServerConfigExpander.getCallbackUrlErrorCodeFieldName(), errorCode);

        // 拼接请求的clientId参数
        redirectParams.put("clientId", HttpServletUtil.getRequest().getParameter("clientId"));

        // 拼接请求的ssoCallback参数
        String ssoCallback = HttpServletUtil.getRequest().getParameter("ssoCallback");
        if (StrUtil.isNotBlank(ssoCallback)) {
            redirectParams.put("ssoCallback", ssoCallback);
        }

        return RedirectUrlBuildUtil.createRedirectUrl(redirectLoginUrl, redirectParams);
    }

    @Override
    public String createErrorTipUrl(String errorCode) {

        // 要跳转的错误界面的url
        String errorViewUrl = CaServerConfigExpander.getErrorViewUrl();

        // 界面内返回原来界面的url
        String referUrl = HttpServletUtil.getRequest().getHeader("Referer");
        String encodeReferer;
        if (StrUtil.isNotBlank(referUrl)) {
            encodeReferer = URLUtil.encode(referUrl);
        } else {
            encodeReferer = StrUtil.EMPTY;
        }

        // 拼接errorCode参数和referUrl参数
        HashMap<String, Object> redirectParams = new HashMap<>();
        redirectParams.put(CaServerConfigExpander.getCallbackUrlErrorCodeFieldName(), errorCode);
        redirectParams.put(CaServerConfigExpander.getErrorViewRedirectUrlFieldName(), encodeReferer);

        return RedirectUrlBuildUtil.createRedirectUrl(errorViewUrl, redirectParams);
    }

}
